from collections import Counter

from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from django.urls import path
from django.contrib.auth import get_user_model

from links_manager.models import Link, Stat, Domain
from app import settings
from settings import views as settings_views
from links_manager import views as links_manager_views

User = get_user_model()


class MyAdminSite(admin.AdminSite):
    site_header = _('Dashboard')
    site_title = _('Dashboard')
    index_title = _('Dashboard')

    def get_urls(self):
        urls = super(MyAdminSite, self).get_urls()

        extra_urls = [
            path('links_manager/link/<int:link_id>/stats/',
                 self.admin_view(links_manager_views.stats), name='links_manager_link_stats'),
            path('settings/', self.admin_view(settings_views.settings),
                 name='settings'),
        ]

        return extra_urls + urls

    def index(self, req, extra_context=None):
        if extra_context is None:
            extra_context = {}

        user = req.user

        # default values
        total_users = 0
        total_links = 0
        total_clicks = 0
        total_domains = 0
        recent_users = []
        recent_links = []

        if user.is_superuser:
            total_users = User.objects.count()
            total_links = Link.objects.count()
            total_clicks = Stat.objects.count()
            total_domains = Domain.objects.count()
            recent_users = User.objects.order_by('-date_joined').all()[:15]
            recent_links = Link.objects.order_by('-created').all()[:15]

            links_list = Link.objects.order_by('created').all()
            stat_list = Stat.objects.order_by('created').all()
        else:
            total_links = Link.objects.filter(user=user).count()
            total_clicks = Stat.objects.filter(user=user).count()
            total_domains = Domain.objects.filter(user=user).count()

            links_list = Link.objects.filter(
                user=user).order_by('created').all()
            stat_list = Stat.objects.filter(
                user=user).order_by('created').all()

        clicks_over_time = Counter((stat.created.strftime('%Y-%m-%d')
                                    for stat in stat_list))
        clicks_over_time = sorted(
            clicks_over_time.items(), key=lambda item: item[0])

        top_all_countries = Counter((stat.country for stat in stat_list))
        top_all_countries = sorted(top_all_countries.items(),
                                   key=lambda item: item[1], reverse=True)

        top_countries_total_clicks = sum(
            clicks for _, clicks in top_all_countries)

        top_countries = top_all_countries[:settings.MAX_ITEMS]
        top_countries = [(country, clicks, round(clicks * 100 / top_countries_total_clicks, 1))
                         for country, clicks in top_countries]

        top_browsers = Counter((stat.browser for stat in stat_list))
        top_browsers = sorted(top_browsers.items(),
                              key=lambda item: item[1], reverse=True)[:settings.MAX_ITEMS]

        top_os = Counter((stat.os for stat in stat_list))
        top_os = sorted(top_os.items(),
                        key=lambda item: item[1], reverse=True)[:settings.MAX_ITEMS]

        top_devices = Counter((stat.device for stat in stat_list))
        top_devices = sorted(top_devices.items(),
                             key=lambda item: item[1], reverse=True)[:settings.MAX_ITEMS]

        domains = Counter((link.domain for link in links_list))
        domains = sorted(
            domains.items(), key=lambda item: item[1], reverse=True)

        # TODO: caching is needed
        referers = Counter((stat.referer for stat in stat_list))
        referers = sorted(referers.items(),
                          key=lambda item: item[1], reverse=True)[:settings.MAX_ITEMS]

        # fetch more data to pass.
        """
        - Total users
        - Total links
        - Total clicks
        - Recent links
        - Recent registered users

        - Clicks Over Time
        - clicks per Geo/Countries
        - Top 10 Countries
        - Links per Domains
        - Most Used Browsers
        - Most Used Operating Systems
        """
        extra_context.update({
            'total_users': total_users,
            'total_links': total_links,
            'total_clicks': total_clicks,
            'total_domains': total_domains,
            'recent_users': recent_users,
            'recent_links': recent_links,
            'links_list': links_list,
            'stat_list': stat_list,
            'clicks_over_time': clicks_over_time,
            'top_countries': top_countries,
            'top_all_countries': top_all_countries,
            'top_browsers': top_browsers,
            'top_os': top_os,
            'top_devices': top_devices,
            'domains': domains,
            'referers': referers
        })

        return super().index(req, extra_context=extra_context)
